package com.koomii.myproject.aspect;

import java.lang.reflect.Method;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import com.koomii.myproject.annotation.IdGenerator;
import com.koomii.myproject.service.IdSequenceService;
import com.koomii.common.util.ArrayUtils;
import com.koomii.common.util.StringUtils;

@Aspect
@Component
public class IdGeneratorAspect {
	private static Log log = LogFactory.getLog(IdGeneratorAspect.class);
	
	@Autowired
	private IdSequenceService idSequenceService;
	
	
	@SuppressWarnings("finally")
	@Around("execution(* com.koomii..dao.*Dao.save*(..))")
	public Object genId(ProceedingJoinPoint pjp) throws Throwable {
		//访问目标方法的参数：
        Object[] args = pjp.getArgs();
      //生成的主键
		Integer id = null;
		try {
			String methodName = pjp.getSignature().getName();
			//
			Class<?>[] clazzs = ((MethodSignature) pjp.getSignature()).getMethod().getParameterTypes();
			
			Method method = pjp.getTarget().getClass().getMethod(methodName, clazzs);
			
			IdGenerator annotation = (IdGenerator) AnnotationUtils.findAnnotation(
					method, IdGenerator.class);
			//Dao中有标记就执行
			if(annotation != null){
		        if(ArrayUtils.isNotEmpty(args)){
		        	//获取主键属性名
		        	String pkPropertyName = annotation.pkPropertyName();
		        	
		        	Object entity = args[0];
		        	//生成主键
		        	String idKey = annotation.idKey();
		        	//标注了idKey才去生成主键
		        	if(StringUtils.isNotEmpty(idKey)){
		        		String v = BeanUtils.getProperty(entity, pkPropertyName);
		        		if(StringUtils.isBlank(v)){
		        			id = idSequenceService.getId(idKey,annotation.allocationSize());
			        		//填充主键
				        	BeanUtils.setProperty(entity, pkPropertyName, id);
		        		}
		        	}else{
		        		log.error("@IdGenerator idKey必填");
		        	}
		        }
			}
			
		}finally {
			//继续原来业务
			Object obj = pjp.proceed(args);
			//返回值为主键Id
			if(id == null){
				return obj;
			}else{
				return id;
			}
		}
	}
}
